#region Microsoft Public License
/*
 * (c) Copyright Chenjun Wu. http://utablesdk.codeplex.com
 * 
 * This source is subject to the Microsoft Public License (Ms-PL).
 * Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
 * All other rights reserved.
 */
#endregion

﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UTable.Input.MultiTouch;
using UTable.Objects.Controls;
using System.Windows;

namespace UTable.Objects.Handlers
{
    public class SingleFingerDrawGestureHandler: SingleFingerHandler
    {
        #region Private Fields

        UIElement _relativeElement;

        private List<Point> _points = new List<Point>();

        #endregion

        #region Constructors

        public SingleFingerDrawGestureHandler(IControl node, UIElement relativeElement)
			: base(node)
		{
            if (relativeElement == null)
                throw new ArgumentNullException("The relative element cannot be null!");

			_relativeElement = relativeElement;

			// initialize the variables
            MinRecognitionConfidence = 0.75;

			EnabledGestures = new List<SingleFingerDrawGestureType>();
			EnabledGestures.Add(SingleFingerDrawGestureType.Line);

            Recognizers = new Dictionary<SingleFingerDrawGestureType, SingleFingerDrawGestureRecognizer>();
            Recognizers.Add(SingleFingerDrawGestureType.Line, new SingleFingerLineGestureRecognizer());
		}

		#endregion

        #region Properties

        public List<SingleFingerDrawGestureType> EnabledGestures { get; set; }

        protected Dictionary<SingleFingerDrawGestureType, SingleFingerDrawGestureRecognizer> Recognizers { get; set; }

        /// <summary>
        /// The minimum recognition confidence
        /// The GestureDetected event can be raised only when the recognition confidence not less than this value 
        /// </summary>
        public double MinRecognitionConfidence { get; set; }

        #endregion

        #region Protected Methods

        protected override void OnSingleFingerDown(FingerEventArgs fArgs)
        {
            _points.Clear();
            Point p = (Node as UIElement).TranslatePoint(fArgs.Position, _relativeElement);
            _points.Add(p);
        }

        protected override void OnSingleFingerMove(FingerEventArgs fArgs)
        {
            Point p = (Node as UIElement).TranslatePoint(fArgs.Position, _relativeElement);
            _points.Add(p);
        }

        protected override void OnSingleFingerUp(FingerEventArgs fArgs)
        {
            SingleFingerDrawGestureRecognitionResult optimalResult = null;
            double optimalConfidence = 0;
            foreach (SingleFingerDrawGestureType gesture in EnabledGestures)
            {
                if (Recognizers.ContainsKey(gesture))
                {
                    SingleFingerDrawGestureRecognizer recognizer = Recognizers[gesture];
                    SingleFingerDrawGestureRecognitionResult result = recognizer.Recognize(_points);
                    if (result != null && result.RecognitionConfidence > optimalConfidence)
                    {
                        optimalResult = result;
                        optimalConfidence = result.RecognitionConfidence;
                    }
                }
            }
            if (optimalResult != null && optimalConfidence > MinRecognitionConfidence && GestureDetected != null)
            {
                // raise the event
                GestureDetected(this, new SingleFingerDrawGestureEventArgs(optimalResult));
            }
        }

        #endregion

		#region Events

		public event SingleFingerDrawGestureEventHandler GestureDetected;

		#endregion

	}

    public enum SingleFingerDrawGestureType
    {
        Line,
        PolyLine,
        RightAngle,
        Circle,
    }

	public delegate void SingleFingerDrawGestureEventHandler(SingleFingerDrawGestureHandler sender, SingleFingerDrawGestureEventArgs args);

    public class SingleFingerDrawGestureEventArgs
    {
        public SingleFingerDrawGestureRecognitionResult RecognitionResult { get; protected set; }

        public SingleFingerDrawGestureEventArgs(SingleFingerDrawGestureRecognitionResult result)
        {
            RecognitionResult = result;
        }
    }
}
